﻿using Sys.Model;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Reflection;
using System.Collections;
using Sys.Data;

namespace Sys.Core
{
    /// <summary>
    /// 资源库操作
    /// </summary>
    /// <typeparam name="T">实体类型</typeparam>
    public abstract class RepositoryAction<T> : RepositoryBase<T> where T : class
    {
        /// <summary>
        /// 查询数据对象
        /// </summary>
        public IQueryable<T> Entities { get { return RC.Set(); } }

        /// <summary>
        /// 查找指定主键的实体记录
        /// </summary>
        /// <param name="key">指定主键</param>
        /// <returns>符合编号的记录</returns>
        public T GetByKey(object key)
        {
            return RC.Set().Find(key);
        }

        /// <summary>
        /// 查找指定条件的实体记录
        /// </summary>
        /// <param name="predicate">指定条件</param>
        /// <returns>符合条件的记录</returns>
        public T GetEntity(Expression<Func<T, bool>> predicate)
        {
            return Entities.FirstOrDefault(predicate);
        }

        /// <summary>
        /// 分页查询
        /// </summary>
        /// <param name="entities">查询数据对象</param>
        /// <param name="rows">显示行数</param>
        /// <param name="page">显示页码</param>
        /// <returns>符合条件结果集</returns>
        public IQueryable<T> EntitiesPage(IQueryable<T> entities, int rows, int page)
        {
            return entities.Skip(rows * (page - 1)).Take(rows);
        }

        /// <summary>
        /// 分页排序查询
        /// </summary>
        /// <param name="entities">查询数据对象</param>
        /// <param name="rows">显示行数</param>
        /// <param name="page">显示页码</param>
        /// <param name="sortname">排序字段</param>
        /// <param name="sortorder">排序类型</param>
        /// <returns>符合条件结果集</returns>
        public IQueryable<T> EntitiesPage(IQueryable<T> entities, int rows, int page, string sortname, string sortorder)
        {
            PropertyInfo property = typeof(T).GetProperty(sortname);
            ParameterExpression parameter = Expression.Parameter(typeof(T), "p");
            MemberExpression propertyAccess = Expression.MakeMemberAccess(parameter, property);
            LambdaExpression orderByExp = Expression.Lambda(propertyAccess, parameter);

            sortorder = sortorder.Equals("asc") ? "OrderBy" : "OrderByDescending";

            MethodCallExpression resultExp = Expression.Call(typeof(Queryable),
                sortorder, new Type[] { typeof(T), property.PropertyType },
                entities.Expression, Expression.Quote(orderByExp));

            return EntitiesPage(entities.Provider.CreateQuery<T>(resultExp), rows, page);
        }
    }
}